package org.light.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.light.domain.Domain;
import org.light.domain.Field;
import org.light.exception.ValidateException;

public class DomainUtil {
	public static Domain findDomainInList(List<Domain> targets, String domainName) throws ValidateException{
		for (Domain d: targets){
			if (d.getStandardName().equals(domainName)) return d;
		}
		throw new ValidateException("域对象"+domainName+"不在列表中！");
	}
	
	public static Domain findDomainInListOrReturnNull(List<Domain> targets, String domainName){
		for (Domain d: targets){
			if (d.getStandardName().equals(domainName)) return d;
		}
		return null;
	}
	
	public static Boolean inDomainList(Domain d,List<Domain> list){
		for (Domain dn :list){
			if (d.getStandardName().equals(dn.getStandardName())){
				return true;
			}
		}
		return false;
	}
	
	public static Boolean nameExistsInDomainList(String domainName,List<Domain> list){
		for (Domain dn :list){
			if (domainName.equals(dn.getStandardName())){
				return true;
			}
		}
		return false;
	}
	
	public static Boolean memberInDomainSet(Set<Domain> targets,Set<Domain> set){
		for (Domain target:targets) {
			for (Domain dn :set){
				if (target.getStandardName().equals(dn.getStandardName())){
					return true;
				}
			}
		}
		return false;
	}
	
	public static Set<String> domainSetToNameSet(Set<Domain> domains){
		Set<String> names = new TreeSet<>();
		for (Domain d:domains) {
			names.add(d.getDomainName().getFieldValue());
		}
		return names;
	}
	
	public static String domainSetToNameSetStr(Set<Domain> domains){
		StringBuilder namesStr = new StringBuilder();
		List<String> names = new ArrayList<>();
		for (Domain d:domains) {
			names.add(d.getDomainName().getFieldValue());
		}
		if (names.size()>1) {
			namesStr.append("{");
			for (String name:names) {
				namesStr.append(name).append(",");
			}
			namesStr.substring(0, namesStr.length()-1);
			namesStr.append("}");
		}else if (names.size()==1) {
			namesStr.append(names.get(0));
		}		
		return namesStr.toString();
	}
	
	public static Boolean inDomainSet(Domain d,Set<Domain> set){
		for (Domain dn :set){
			if (d.getStandardName().equals(dn.getStandardName())){
				return true;
			}
		}
		return false;
	}
	
	public static List<Domain> filterDataDomainList(List<List<Domain>> dataDomains, String domainName) throws ValidateException{
		List<Domain> results = new ArrayList<Domain>();
		for (List<Domain> list:dataDomains) {
			for (Domain d: list){
				if (d.getStandardName().equals(domainName)) results.add(d);
			}
		}
		return results;
	}
	
	public static  List<List<Domain>> removeDataDomainsFromLists(List<List<Domain>> dataDomains, String domainName) throws ValidateException{
		List<List<Domain>> results = new ArrayList<>();
		for (List<Domain> list:dataDomains) {	
			List<Domain> rows = new ArrayList<>();
			for (Domain d:list) {				
				if (!d.getStandardName().equals(domainName)) rows.add(d);
			}
			if (rows.size()>0)results.add(rows);
		}
		return results;
	}
	
	public static List<List<Domain>> addDataDomainToList(List<List<Domain>> dataDomains, Domain datadomain) throws ValidateException{
		List<List<Domain>> results = new ArrayList<>();
		boolean found = false;
		for (List<Domain> list:dataDomains) {
			if (list.size()>0) {
				if (list.get(0).getStandardName().equals(datadomain.getStandardName())) {
					list.add((Domain)datadomain.deepClone());
					found =true;
				}
				results.add(list);
			}
		}
		if (!found) {
			List<Domain> list = new ArrayList<>();
			list.add((Domain)datadomain.deepClone());
			results.add(list);
		}
		return results;
	}
	
	public static List<List<Domain>> deleteDataDomainFromList(List<List<Domain>> dataDomains, String datadomainname, int pos) throws ValidateException{
		List<List<Domain>> results = new ArrayList<>();
		for (List<Domain> list:dataDomains) {
			if (list==null||list.size()==0) continue;
			if (list.get(0).getStandardName().equals(datadomainname)&&list.size()>pos) {
				list.remove(pos);				
			}
			results.add(list);
		}
		return results;
	}
	
	public static List<List<Domain>> deleteAllDataDomainsFromList(List<List<Domain>> dataDomains, String datadomainname) throws ValidateException{
		List<List<Domain>> results = new ArrayList<>();
		for (List<Domain> list:dataDomains) {
			List<Domain> resultList = new ArrayList<>();
			for (Domain d: list) {
				if (!d.getStandardName().equals(datadomainname)) resultList.add(d);
			}
			if (resultList.size()>0) results.add(resultList);
		}
		return results;
	}
	
	public static List<List<Domain>> updateDataDomainFromList(List<List<Domain>> dataDomains, Domain datadomain,int pos) throws ValidateException{
		List<List<Domain>> results = new ArrayList<>();
		for (List<Domain> list:dataDomains) {
			if (list == null || list.size()==0) continue;
			if (list.get(0).getStandardName().equals(datadomain.getStandardName())&&list.size()>pos) list.set(pos, (Domain)datadomain.deepClone());
			results.add(list);
		}
		return results;
	}
	
	public static boolean validateId(String val) {
		if (StringUtil.isBlank(val)) return true;
		boolean flag = false;
		try {
			String regex = "^([0]|[1-9][0-9]*)$";
			Pattern p = Pattern.compile(regex);
			Matcher m = p.matcher(val);
			if (m.find()) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return flag;
	}
	
	public static Domain findDataDomainInListByDomainNameValue(List<Domain> targets,String nameValue) {
		if (!StringUtil.isBlank(nameValue)) {
			for (Domain d:targets) {
				if (d.getDomainName().getFieldValue().equals(nameValue))
					return d;
			}
		}
		return null;
	}
	
	public static Boolean setContainsDomain(Set<Domain> set, String domainName) {
		for (Domain d : set) {
			if (d.getStandardName().equals(domainName))
				return true;
		}
		return false;
	}
	
	public static Domain lookupDoaminInSet(Set<Domain> set, String domainName) {
		for (Domain d : set) {
			if (d.getStandardName().equals(domainName)&&!d.isLegacy())
				return d;
		}
		return null;
	}
	
	public static Field findDomainFieldByFieldName(Domain d,String fieldName) {
		for (Field f:d.getFields()) {
			if (f.getFieldName().equals(fieldName)) return f;
		}
		return null;
	}	
	
	public static boolean expendFixedName(Domain d) {
		for (Field f:d.getFields()) {
			String fieldName = f.getFieldName();
			String fixedName = f.getFixedName();
			if (!StringUtil.isBlank(fixedName)&&!fixedName.equals(fieldName)) return true;
		}
		return false;
	}
}
